'''
Module myPlayerBrain: the sample Python AI.  Start with this project but write 
your own code as this is a very simplistic implementation of the AI.

Created on Dec 7, 2011

@author: malcolmm
'''

import random
import utilities, playerTurn, debug
from api import board, player

class MyPlayerBrain(object):
    '''The Python AI class.  This class must have the methods setup and turn.'''
    
    def __init__(self):
        self.name = "Guido van Rossum"  #The name of the player.
        self.avatar = None              #The player's avatar (optional).  
                                        #Size must be 32 x 32.
    
    def setup(self, gMap, you, allPlayers, startPoints, isGameStart):
        '''
        Return your AI's requested starting point (a BoardLocation).
        
        Called when your robot must be placed on the board.  This is called at 
        the start of the game and each time your robot dies.  Return the 
        BoardLocation on which to place your unit (location and direction).
        
        gMap -- The current GameMap.  There will be no units on this map.
        you -- Your Player object.
        allPlayers -- List of all Player objects (including you).
        startPoints -- List of all (x, y) position(s) on the map where you can 
            place your robot. This will be a single point unless another 
            robot is on your archive point.
        isGameStart -- True if start of game.  False if re-entering the game.
        
        '''
        return board.BoardLocation(startPoints[0], "NORTH")
    
    def turn(self, gMap, you, allPlayers, cards):
        '''
        Return your AI's requested PlayerTurn.
        
        Called each time the system needs another turn.  If you do not return a 
        valid turn, the game will randomly move one of your units.  **This call 
        must return in under 1 second.**  If it has not returned in 1 second the 
        call will be aborted and a random move will be assigned.
        
        gMap -- The current GameMap with all units on it.
        you -- Your Player object.  This is created for each call.
        allPlayers -- List of all Player objects including you.  This is 
            created for each call.
        cards -- List of all Card objects you can pick from.  This does not 
            include locked cards.
        
        '''
        # if hurt bad, consider power down
        powerDown = False
        if you.damage > 5 and random.randrange(3) == 0:
            powerDown = True
        
        # get 40 sets, pick the one that's closest to the flag
        bestCards = None
        bestDiff = float('infinity')
        okDiff = random.randint(0, 3)
        flagStates = [fs for fs in you.flagStates if not fs.touched]
        flagPoint = flagStates[0].position if len(flagStates) > 0 else (5, 6)
        for _ in range(40):
            # pick 5 (or fewer if locked) random cards
            moveCards = [None for i in range(5)]
            cardUsed  = [False for i in range(len(cards))]
            for i in range(5 - you.numLockedCards()):
                while True:
                    index = random.randrange(len(cards))
                    if cardUsed[index]:
                        continue
                    moveCards[i] = cards[index]
                    cardUsed[index] = True
                    break
            # add in the locked cards
            for i in range(5 - you.numLockedCards(), 5):
                moveCards[i] = you.cards[i]
            # run it
            moveTo = utilities.cardDestination(gMap, you.robot.location, moveCards)
            if moveTo.dead:
                continue
            # if better than before, use it
            diff = ( abs(flagPoint[0] - moveTo.location.mapPosition[0]) + 
                     abs(flagPoint[1] - moveTo.location.mapPosition[1]) )
            if diff <= okDiff:
                return playerTurn.PlayerTurn(moveCards, powerDown)
            if diff < bestDiff:
                bestDiff = diff
                bestCards = moveCards
            
        return playerTurn.PlayerTurn( 
                bestCards if bestCards is not None else list(), powerDown)
    # end method: turn
# end class: MyPlayerBrain